// Number
// 整数+小数
var a = 10.1
console.log(typeof(a)) 

// String
// "", ''
var a = ''
console.log(typeof(a)) 

// String 模板
// ``
var a = '小红'
console.log(`你好, ${a}`)

// Boolean
// true/false
var a = true
if (a) {
    console.log(`你好, ${a}`)
}

// Array Go: a = [10]string
// 构造函数  Array 类型,  Array()  new a = [], a.push(params)
// PUSH/Pop
var a = Array(1, 'string', true, [], {})
a[0] = '100'
a[6] = 'external'
a.push('A', 'B')
console.log(a.pop())
console.log(a.pop())
console.log(a)

// Array Go: a = [10]string
// 构造函数  Array 类型,  Array()  new a = [], a.push(params)
// Unshift/shift
var a = Array(1, 'string', true, [], {})
a.unshift('A', 'B')
console.log(a.shift())
console.log(a.shift())
console.log(a)

// Array Splice
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
console.log(arr.splice(2, 3, 'Google', 'Facebook'))  // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
console.log(arr) // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

// Array sort  sort.SortIntSlice() type Sort interface
// 默认按照首字符进行排序
// 通过compareFn指定排序逻辑
var arr = [100, 2, 15, 30, 7, 6];
arr.sort((a, b) => a - b)
console.log(arr)
arr.reverse()
console.log(arr)

// Array Contact/Slice
var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
console.log(added) // ['A', 'B', 'C', 1, 2, 3]

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
console.log(arr.slice(0, 3)) // 从索引0开始，到索引3结束，但不包括索引3: ['A', 'B', 'C']
console.log(arr.slice(3)) // 从索引3开始到结束: ['D', 'E', 'F', 'G'] a[3:]

// Object
// var ob1 = new Object()
var ob1 = {name: "老喻", age: 33}
// ob1.name = '老喻'
// ob1.age = 33
console.log(ob1)
console.log(ob1.hasOwnProperty("fovor"))


// 变量作用域提升, m1没有声明
// function foo() {
//     console.log('Hello, ' + y);
//     var y = 'Bob';
// }
// foo()

var m2 = `这是一个
多行
字符串`
console.log(m2)

// try  catch
try {
    var s = null
    s.length
} catch (error) {
    console.log('error string: '+ error)
}

// Function Method
var person = {name: '张三', age: 22}
person.greet = function() {
    let that = this
    return function() {
        console.log(`hello, my name is ${that.name}`)
    }
}
person.greet()()

// Arrow Function
function sum(x,y) {return x+y}
console.log(sum(1, 2))

// 变量命名
let f2 = function(x, y) {return x+y}
f2(1,2)

let f3 = (x,y) => {return x +y }
console.log(f3(10,10))


var person = {name: '张三', age: 22}
person.greet = function() {
    // 箭头函数帮我们处理了 this的指向问题
    return () => {
        console.log(`hello, my name is ${this.name}`)
    }
}
person.greet()()

// PKG
// export {} ==> {}
// defaut<固定语法> as pkg
import pkg from './profile.mjs'
console.log(pkg.firstName, pkg.lastName, pkg.year)


// for 循环
var i = 0
for (;i<10;) {
    console.log(i)
    i++
}

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};

for (let key in o) {
    console.log(key, o[key])
}

var a = ['A', 'B', 'C'];
a.name = 'hello'
for (let key in a) {
    console.log(key, a[key])
}

// for of 获取的是值,而不是属性
for (let item of a) {
    console.log(item)
}

// 编码map
for (let key of Object.keys(o)) {
    console.log(key, o[key])
}

// 任务一个Array, 都有forEach方法
// 他是一个函数, 这些元素是并行处理(map)
// type callback function ()
// cb = func() {
//    go 
// }
// Array.ForEach(cb)
a.forEach(element => {
    console.log(element)
});

// 单线程异步模型
function callback() {
    console.log('Done');
}
console.log('before setTimeout()');
setTimeout(callback, 5000); // 1秒钟后调用callback函数
console.log('after setTimeout()');

// 如何编写类似于setTimeout的函数, 是获取数据getData, 要求立马返回, 不能阻塞
// 通过一种特殊的写法: sucess(data) error(err)


function getData(success, reject) {
    let ok = true
    // 业务逻辑非常耗时, 比如2s服务端才返回数据
    setTimeout(() => {
        if (ok) {
            // 成功着调用success 回调
        success({code: 0, data:{name: '老王', age:33}})
        } else {
            // 失败者调用reject回到
        reject({code: 500, data:{message: '获取数据异常'}})
        }
    }, 5000)
}

// 
getData((data)=>{ console.log(data)}, (error)=> {console.log(error)})

// 采用Promise, 相比于我们自己传递回调函数, 添加了一个语法糖, 做成一个了链式调用
var p1 = new Promise(getData)
p1.then((resp)=> {
    console.log(resp)
}).catch((err) => {
    console.log(err)
}).finally(() => {
    console.log("finally")
})


// Async + Promise对象 
// 用Go实现性能的代码(channel 会有锁), 比如自己实现一个类似于Kafaka的中间件(), nats(完全基于回调)
// go dowork(sucessCallbak, failCallback)
async function testWithAsync() {
    var p1 = new Promise(getData)

    try {
        var resp = await p1
        console.log(resp)
    } catch (err) {
        console.log(err)
    }
}

testWithAsync()
